/**
 * 目前不支持自闭合标签
 * 切割字符串为token集合
 */

const State = {
    initial: 1, //初始状态
    tagOpen: 2, //标签开始状态
    tagName: 3, //标签名称状态
    text: 4, //文本状态
    tagEnd: 5, //结束标签状态
    tagEndName: 6 //结束标签名称状态
};
//一个辅助函数，判断是不是字母
function isAlpha(char) {
    return char >= "a" && char <= "z" || char >= "A" && char <= "Z";
}
var i = 0;
//接搜末班字符串作为参数，并将模板切割为Token返回
function tokenzie(str) {
    //状态机的当前状态:初始状态
    let currentState = State.initial;
    //用于缓存字符串
    const chars = [];
    //生成的token会出道tokens数组中，并作为函数的返回值返回
    const tokens = [];
    //使用while循环开启自动机，只要字符串没有被消费尽，自动机机会一直允许
    while (str && i < 100) {
        i++;

        //查看第一个字符，注意，这里只是查看，没有消费该字符
        const char = str[0];
        console.log("chars", chars, 'char', char, 'State.tagName', State.tagName)
        switch (currentState) {
            case State.initial:
                //状态当前处于初始化状态
                if (char === "<") {
                    //状态机切换到标签开始状态
                    currentState = State.tagOpen;
                    str = str.slice(1);
                } else if (isAlpha(char)) {
                    currentState = State.text;
                    //将当前字母缓存到chars数组
                    chars.push(char);
                    //3.消费当前字符串
                    str = str.slice(1);
                }
                break;

                //状态机处于标签开始状态
            case State.tagOpen:
                if (isAlpha(char)) {
                    //1.遇到字母，切换成标签名称状态
                    currentState = State.tagName;
                    chars.push(char);
                    str = str.slice(1);
                } else if (char === "/") {
                    currentState = State.tagEnd;
                    str = str.slice(1);
                }
                break;
                //状态机当前处于标签名称状态
            case State.tagName:
                console.log("Alpha", isAlpha(char), char)
                if (isAlpha(char)) {
                    //遇到字母，由于当前处于标签名称状态，所以不需要切换状态
                    //当时需要将当前字符串缓存到chars数组
                    chars.push(char);
                    //消费当前已复查
                    str = str.slice(1);
                } else if (char == ">") {
                    //遇到字符>切换到初始状态
                    currentState = State.initial;
                    //2.同时创建一个标签Token，并添加到tokens数组中
                    tokens.push({
                        type: "tag",
                        name: chars.join("")
                    });
                    //3.chars数组的内容已经被消费，清空它
                    chars.length = 0;
                    //4.同时消费当前字符串
                    str = str.slice(1);
                }
                break;
                //状态机当前处于文本状态
            case State.text:
                if (isAlpha(char)) {
                    //1.遇到字母，保持状态不变，但应该见当前字符缓存到chars数组
                    chars.push(char);
                    //2.消费当前字符
                    str = str.slice(1);
                } else if (char === "<") {
                    //1.遇到字符""<"，切换到标签开始状态
                    currentState = State.tagOpen;
                    //2.从文本状态--》标签开始，此时应该创建文本Token，并添加到tokens数组
                    tokens.push({
                        type: "text",
                        content: chars.join("")
                    });
                    //3.chars数组的内容已经被消费，清空它
                    chars.length = 0;
                    //4.消费当前字符
                    str = str.slice(1);
                }
                break;
                //状态机处于标签结束状态
            case State.tagEnd:
                if (isAlpha(char)) {
                    //遇到字母，切换到结束标签名称状态
                    currentState = State.tagEndName;
                    //将当前字符缓存到chars数组
                    chars.push(char);
                    //消费当前字符
                    str = str.slice(1);
                }
                break;
                //状态机当前处于结束标签名状态
            case State.tagEndName:
                if (isAlpha(char)) {
                    chars.push(char);
                    str = str.slice(1);
                } else if (char === ">") {
                    currentState = State.initial;
                    //从结束标签名称状态--》初始化状态，应该结束标签名称Token
                    //注意，此时chars数组中缓存的内容就是标签名称
                    tokens.push({
                        type: "tagEnd",
                        name: chars.join("")
                    });
                    console.log("tagEndName", chars[0])
                        //chars数据已经被消费完了，清空它
                    chars.length = 0;
                    str = str.slice(1);

                }
                break;

        }
    }
    //最后，返回tokens
    return tokens;
}